package com.ray.activiti.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ray.activiti.common.Constant;
import com.ray.activiti.common.entity.NewTaskInfo;
import com.ray.activiti.common.page.Page;
import com.ray.activiti.common.page.PageHelper;
import com.ray.activiti.common.utils.ActUtils;
import com.ray.activiti.dto.ProcessNodeDto;
import com.ray.activiti.dto.ProcessTaskDto;
import com.ray.activiti.enums.RunType;
import com.ray.activiti.service.ActModelerService;
import com.ray.activiti.service.ExtendActBusinessService;
import com.ray.activiti.service.ExtendActFlowbusService;
import com.ray.activiti.service.ExtendActModelerService;
import com.ray.activiti.service.ExtendActNodesetService;
import com.ray.activiti.service.ExtendActTasklogService;
import com.ray.activiti.table.entity.ExtendActBusiness;
import com.ray.activiti.table.entity.ExtendActFlowbus;
import com.ray.activiti.table.entity.ExtendActModel;
import com.ray.activiti.table.entity.ExtendActNodeset;
import com.ray.activiti.table.entity.ExtendActTasklog;
import com.ray.activiti.table.mapper.ActExtendMapper;
import com.ray.activiti.table.mapper.ExtendActModelMapper;
import com.ray.activiti.utils.CallBackUtil;
import com.ray.activiti.vo.ActNode;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.zjhc.flyhong.common.function.exception.BussinessException;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.util.UUIDUtil;

/**
 * 类的功能描述.
 * activiti模型接口实现类
  * @Auther ray  qray686898@163.com
 * @Date 2017/12/28
 * @代码参考或来自  https://github.com/huangxianyuan/hxyFrame
 */
@Service
public class ActModelerServiceImpl implements ActModelerService{

    @Resource(name = "repositoryService")
    private RepositoryService repositoryService;

    @Resource(name = "objectMapper")
    private ObjectMapper objectMapper;

    @Autowired
    private ExtendActModelMapper extendActModelMapper;
    
    @Autowired
    ExtendActModelerService extendActModelService;
    
    @Autowired
    private ActExtendMapper actExtendMapper;

    @Autowired
    private ExtendActNodesetService nodesetService;

    @Autowired
    private ExtendActBusinessService businessService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    protected ExtendActTasklogService tasklogService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ExtendActFlowbusService flowbusService;


    @Autowired
    private HistoryService historyService;



    @SuppressWarnings("deprecation")
	@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public String CreateModeler(ExtendActModel extendActModelEntity,LoginUser user) throws Exception {
        //editorInfo
        ObjectNode editorNode = objectMapper.createObjectNode();
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);

        //构建模型
        Model model = repositoryService.newModel();

        //metaInfo 元信息
        ObjectNode metaNode = objectMapper.createObjectNode();
        metaNode.put(ModelDataJsonConstants.MODEL_NAME,extendActModelEntity.getName());
        metaNode.put(ModelDataJsonConstants.MODEL_REVISION,model.getVersion());
        metaNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION,extendActModelEntity.getRemark());
        model.setName(extendActModelEntity.getName());
        model.setMetaInfo(metaNode.toString());
        model.setTenantId(user.getTenantId());
        //获取business
        if(StringUtils.isBlank(extendActModelEntity.getExtendActBusinessId())){
        	throw new BussinessException(-1, "业务没有选择");
        }
        ExtendActBusiness actbus = businessService.queryObject(extendActModelEntity.getExtendActBusinessId());
        model.setKey(actbus.getActKey());
        //保存模型
        repositoryService.saveModel(model);
        repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes("utf-8"));

        //保存模型扩展表
        extendActModelEntity.setActVersion(model.getVersion());
        extendActModelEntity.setModelId(model.getId());
        extendActModelEntity.setStatus(StringUtils.isEmpty(model.getDeploymentId())? Constant.YESNO.NO.getValue():Constant.YESNO.YES.getValue());
        extendActModelEntity.setDeploymentId(model.getDeploymentId());
        extendActModelMapper.save(extendActModelEntity);
        return model.getId();
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public  List<Map<String,String>> getflows(String contextPath,String modelId) throws Exception {
        //转换
        JsonNode jsonNode = objectMapper.readTree(repositoryService.getModelEditorSource(modelId));
        BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode);
        //取第一个流程,注：不包括子流程 待开发
        if(bpmnModel.getProcesses().size()<1){
            return null;
        }
        Process process = bpmnModel.getProcesses().get(0);
        Collection<FlowElement> flowElements = process.getFlowElements();
        //取得其中关键数据
        List<Map<String,String>> lists=new ArrayList<Map<String,String>>();
        Map<String,String> tempmap=null;
        Map<String, Map<String,String>> allmap=new HashMap<String, Map<String,String>>();
        int index = 0; 
        for (FlowElement flowElement : flowElements) {
            tempmap=new HashMap<String,String>();
            tempmap.put("treeId", flowElement.getId());
            tempmap.put("modelId", modelId);
            tempmap.put("index", (index++)+"");
            if(flowElement instanceof StartEvent){
                tempmap.put("treeName", "开始节点");
                tempmap.put("type", "1");
                tempmap.put("icon", contextPath+"/statics/images/sys/none.png");
            }else if(flowElement instanceof UserTask){
                tempmap.put("type", "2");
                tempmap.put("treeName",flowElement.getName());
                tempmap.put("icon", contextPath+"/statics/images/sys/typeuser.png");
            }else if(flowElement instanceof ExclusiveGateway){
                tempmap.put("type", "3");
                tempmap.put("treeName",flowElement.getName());
                tempmap.put("icon", contextPath+"/statics/images/sys/exclusive.png");
            } else if(flowElement instanceof SequenceFlow){
                tempmap.put("type", "4");
                tempmap.put("treeName",flowElement.getName());
                tempmap.put("icon", contextPath+"/statics/images/sys/sequenceflow.png");
            }else if(flowElement instanceof EndEvent){
                tempmap.put("type", "5");
                if(StringUtils.isNotEmpty(flowElement.getName())){
                    tempmap.put("treeName",flowElement.getName());
                }else{
                    tempmap.put("treeName","结束");
                }
                tempmap.put("icon", contextPath+"/statics/images/sys/endnone.png");
            }
            String pid="0";
            if(flowElement instanceof SequenceFlow){
                pid=((SequenceFlow) flowElement).getSourceRef();
                tempmap.put("tarid", ((SequenceFlow) flowElement).getTargetRef());
                lists.add(tempmap);
            }else{
                List<SequenceFlow> sqlist= ((FlowNode) flowElement).getIncomingFlows();
                if(sqlist!=null&&sqlist.size()>0){
                    SequenceFlow tem1=sqlist.get(0);
                    pid=tem1.getSourceRef();
                }
            }
            tempmap.put("treePid", pid);
            allmap.put(flowElement.getId(),tempmap);
        }
        for(Map<String,String> map:lists){
            String pid=map.get("treePid");
            //如果该元素的父节点不为空 ，且父节点是 分支类型的
            if(allmap.get(pid)!=null&&"3".equals(allmap.get(pid).get("type"))){
                allmap.get(map.get("tarid")).put("treePid", map.get("treeId"));
            }else{
                allmap.remove( map.get("treeId"));
            }
        }
        lists.clear();
        for (Map.Entry<String, Map<String, String>> entry : allmap.entrySet()) {
            String typex=entry.getValue().get("type");
            if("2".equals(typex)){
                entry.getValue().put("treePid", "0");
            }else if("1".equals(typex)){
                continue;
            }
            lists.add(entry.getValue());
        }
        return lists;
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public byte[] showFlowImg(String modelId) {
        if(StringUtils.isEmpty(modelId)){
            throw new BussinessException(-1,"流程模型id不能为空!");
        }
        try {
            byte[] bytes = repositoryService.getModelEditorSourceExtra(modelId);
            return bytes;
        } catch (Exception e) {
            throw new BussinessException(-1,"流程图片加载失败!");
        }
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public List<Map<String,Object>> queryFlowsByActKey(String actKey,LoginUser user) {
        return actExtendMapper.queryFlowsByActKey(actKey,user.getTenantId());
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public ActNode getStartFlowInfo(String deployId) throws IOException {
        Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deployId).singleResult();
        Model model = repositoryService.createModelQuery().deploymentId(deployment.getId()).singleResult();
        byte[] bytes = repositoryService.getModelEditorSource(model.getId());
        JsonNode jsonNode = objectMapper.readTree(bytes);
        BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(jsonNode);
        Process process = bpmnModel.getProcesses().get(0);
        List<FlowElement> flowElements = (List<FlowElement>)process.getFlowElements();
        //流程的开始节点
        StartEvent startEvent = null;
        for (FlowElement flowElement : flowElements) {
            if(flowElement instanceof StartEvent){
                startEvent = (StartEvent)flowElement;
                break;
            }
        }
        FlowElement fe = null;
        //获取开始的出口流向
        SequenceFlow sequenceFlow = startEvent.getOutgoingFlows().get(0);
        for (FlowElement flowElement : flowElements) {
            //抛出异常，开始节点后的第一个节点不为userTask
            if(flowElement.getId().equals(sequenceFlow.getTargetRef())){
                if(flowElement instanceof UserTask || flowElement instanceof EndEvent){
                    fe =flowElement;
                    break;
                } else{
                    throw new BussinessException(-1,"流程设计错误，【开始】之后只能是审批节点或结束节点");
                }
            }
        }
        if(fe!=null){
            //查询该节点的类型
            ExtendActNodeset nodesetEntity = nodesetService.queryByNodeIdModelId(fe.getId(), model.getId());
            if(nodesetEntity == null || StringUtils.isEmpty(nodesetEntity.getNodeType())){
                throw new BussinessException(-1,"流程设计错误，【开始】之后只能是审批节点或结束节点");
            }
            ActNode result = new ActNode();
            result.setNodeId(fe.getId());
            result.setModelId(model.getId());
            result.setNodeType(nodesetEntity.getNodeType());
            result.setNodeAction(nodesetEntity.getNodeAction());
            return result;
        }
        return null;
    }

   
    /**
     * 方法更改了的表
     * 1.当前业务表流程相关信息
     * 2.流程业务关系表extend_act_flowbus
     * 3.流程任务扩展表extend_act_tasklog
     * @param processTaskDto
     * @throws Exception
     */
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void startFlowAndExeNextTask(ProcessTaskDto processTaskDto,ActNode startNode,LoginUser user) throws Exception {
    	 if(StringUtils.isEmpty(startNode.getNodeId())){
             throw new BussinessException(-1,"流程节点ID不能为空");
         }
    	
    	if(StringUtils.isEmpty(processTaskDto.getActKey())){
            throw new BussinessException(-1,"流程actKey不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getBusId())){
            throw new BussinessException(-1,"业务ID不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义ID不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getNodeType())){
            throw new BussinessException(-1,"节点类型不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getNextUserIds())&&!"5".equals(processTaskDto.getNodeType())){
            throw new BussinessException(-1,"处理人不能为空");
        }
        //查询流程业务关联信息
        //ExtendActBusiness businessEntity = businessService.queryByActKey(processTaskDto.getActKey());
       
        ExtendActNodeset nodeSet = nodesetService.queryByNodeId(startNode.getNodeId());
        
        //读取需要判断的条件字段，做为流程变量
        Map<String, Object> variables = new HashMap<String, Object>();
        
        //设置流程变量
        CallBackUtil.setVariables(nodeSet,processTaskDto,variables);
        
        //启动流程并设置启动变量（条件变量）
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processTaskDto.getDefId(), processTaskDto.getBusId(), variables);
        processTaskDto.setInstanceId(processInstance.getId());
        //更新当前业务表
        Date curentTime = new Date();
     
        //保存任务日志表
        ExtendActTasklog tasklog = new ExtendActTasklog();
        tasklog.setId(UUIDUtil.getUUID());
        tasklog.setBusId(processTaskDto.getBusId());
        tasklog.setDefId(processTaskDto.getDefId());
        tasklog.setInstanceId(processTaskDto.getInstanceId());
        tasklog.setTaskName("提交");
        tasklog.setDealTime(curentTime);
        tasklog.setDealId(user.getUserId());
        tasklog.setAppAction(Constant.ActTaskResult.AGREE.getValue());
        tasklog.setAppOpinion(processTaskDto.getRemark());
        //保存流程业务关系表
        ExtendActFlowbus flowBus = new ExtendActFlowbus();
        flowBus.setId(UUIDUtil.getUUID());
        flowBus.setBusId(processTaskDto.getBusId());
        flowBus.setDefid(processTaskDto.getDefId());
        flowBus.setInstanceId(processTaskDto.getInstanceId());
        flowBus.setStartTime(curentTime);
        flowBus.setActKey(processTaskDto.getActKey());
        flowBus.setStatus(Constant.ActStauts.APPROVAL.getValue());
        flowBus.setStartUserId(user.getUserId());
        flowbusService.save(flowBus);
        //代理人设置 待完善
        // TODO: 2017/8/4  代理人设置 待完善
        //如果第一个节点是审批节点
        if(Constant.NodeType.EXAMINE.getValue().equals(processTaskDto.getNodeType())){
            List<Task> tasks = taskService.createTaskQuery().processDefinitionId(processTaskDto.getDefId()).processInstanceId(processTaskDto.getInstanceId()).list();
            for (Task task:tasks){
                //设置下一个任务处理人
                taskService.setAssignee(task.getId(),user.getUserId());
                //记录任务日志
                ExtendActTasklog tasklogEntity = new ExtendActTasklog();
                tasklogEntity.setId(UUIDUtil.getUUID());
                tasklogEntity.setBusId(processTaskDto.getBusId());
                tasklogEntity.setDefId(processTaskDto.getDefId());
                tasklogEntity.setInstanceId(processTaskDto.getInstanceId());
                tasklogEntity.setTaskId(task.getId());
                tasklogEntity.setTaskName(task.getName());
                tasklogEntity.setAdvanceId(user.getUserId());
                tasklogEntity.setCreateTime(task.getCreateTime());
                tasklogService.save(tasklogEntity);
                
                //查询流程配置的回调函数
                ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(task.getTaskDefinitionKey());
                //如果该节点配置有回调函数，则执行回调
                if(nodesetEntity != null){
                	CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.START.getType());
                }
                //默认第一个节点是是自己 所有启动的时候会执行到第二个
                processTaskDto.setTaskId(task.getId());
                doActTask(processTaskDto, new HashMap<String, Object>(), user);
            }
            //如果第一个节点是结束节点 也就是空流程
        }else if(Constant.NodeType.END.getValue().equals(processTaskDto.getNodeType())){
            tasklog.setAppOpinion("空流程结束");
            //流程完成后，更改当前业务表的流程信息
            //更新流程业务关系表
            ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
            flowbusEntity.setBusId(processTaskDto.getBusId());
            flowbusEntity.setStatus(Constant.ActStauts.END.getValue());
            flowbusService.updateByBusId(flowbusEntity);
            //获取下一个人工任务节点，进行回调执行
            ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processTaskDto.getDefId());
            //获取流程定义的全部节点
            List<ActivityImpl> activities = processDefinitionEntity.getActivities();
            for(ActivityImpl node:activities){
                //节点类型为结束节点
                String type = (String)node.getProperty("type");
                if("endEvent".equals(type)){
                    //查询流程配置的回调函数
                    ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(node.getId());
                    //如果该节点配置有回调函数，则执行回调
                    if(nodesetEntity != null){
                    	CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.END.getType());
                    }
                    //流程结束发送通知 待完善
                    // TODO: 2017/8/4 流程结束发送通知 待完善
                }
            }
        }else {
            throw new BussinessException(-1,"流程设计错误!");
        }
        //保存扩展任务日志
        tasklogService.save(tasklog);
    }
    
    /**
     * 方法更改了的表
     * 1.当前业务表流程相关信息
     * 2.流程业务关系表extend_act_flowbus
     * 3.流程任务扩展表extend_act_tasklog
     * @param processTaskDto
     * @throws Exception
     */
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void startFlow(ProcessTaskDto processTaskDto,ActNode startNode,LoginUser user) throws Exception {
    	 if(StringUtils.isEmpty(startNode.getNodeId())){
             throw new BussinessException(-1,"流程节点ID不能为空");
         }
    	
    	if(StringUtils.isEmpty(processTaskDto.getActKey())){
            throw new BussinessException(-1,"流程actKey不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getBusId())){
            throw new BussinessException(-1,"业务ID不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义ID不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getNodeType())){
            throw new BussinessException(-1,"节点类型不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getNextUserIds())&&!"5".equals(processTaskDto.getNodeType())){
            throw new BussinessException(-1,"处理人不能为空");
        }
        //查询流程业务关联信息
        //ExtendActBusiness businessEntity = businessService.queryByActKey(processTaskDto.getActKey());
       
        ExtendActNodeset nodeSet = nodesetService.queryByNodeId(startNode.getNodeId());
        
        //读取需要判断的条件字段，做为流程变量
        Map<String, Object> variables = new HashMap<String, Object>();
        
        //设置流程变量
        CallBackUtil.setVariables(nodeSet,processTaskDto,variables);
        
        //启动流程并设置启动变量（条件变量）
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processTaskDto.getDefId(), processTaskDto.getBusId(), variables);
        processTaskDto.setInstanceId(processInstance.getId());
        //更新当前业务表
        Date curentTime = new Date();
     
        //保存任务日志表
        ExtendActTasklog tasklog = new ExtendActTasklog();
        tasklog.setId(UUIDUtil.getUUID());
        tasklog.setBusId(processTaskDto.getBusId());
        tasklog.setDefId(processTaskDto.getDefId());
        tasklog.setInstanceId(processTaskDto.getInstanceId());
        tasklog.setTaskName("提交");
        tasklog.setDealTime(curentTime);
        tasklog.setDealId(processTaskDto.getNextUserIds());
        tasklog.setAppAction(Constant.ActTaskResult.AGREE.getValue());
        tasklog.setAppOpinion(processTaskDto.getRemark());
        //保存流程业务关系表
        ExtendActFlowbus flowBus = new ExtendActFlowbus();
        flowBus.setId(UUIDUtil.getUUID());
        flowBus.setBusId(processTaskDto.getBusId());
        flowBus.setDefid(processTaskDto.getDefId());
        flowBus.setInstanceId(processTaskDto.getInstanceId());
        flowBus.setStartTime(curentTime);
        flowBus.setActKey(processTaskDto.getActKey());
        flowBus.setStatus(Constant.ActStauts.APPROVAL.getValue());
        flowBus.setStartUserId(user.getUserId());
        flowbusService.save(flowBus);
        //代理人设置 待完善
        // TODO: 2017/8/4  代理人设置 待完善
        //如果第一个节点是审批节点
        if(Constant.NodeType.EXAMINE.getValue().equals(processTaskDto.getNodeType())){
            List<Task> tasks = taskService.createTaskQuery().processDefinitionId(processTaskDto.getDefId()).processInstanceId(processTaskDto.getInstanceId()).list();
            for (Task task:tasks){
                //设置下一个任务处理人
                taskService.setAssignee(task.getId(),processTaskDto.getNextUserIds());
                //记录任务日志
                ExtendActTasklog tasklogEntity = new ExtendActTasklog();
                tasklogEntity.setId(UUIDUtil.getUUID());
                tasklogEntity.setBusId(processTaskDto.getBusId());
                tasklogEntity.setDefId(processTaskDto.getDefId());
                tasklogEntity.setInstanceId(processTaskDto.getInstanceId());
                tasklogEntity.setTaskId(task.getId());
                tasklogEntity.setTaskName(task.getName());
                tasklogEntity.setAdvanceId(processTaskDto.getNextUserIds());
                tasklogEntity.setCreateTime(task.getCreateTime());
                tasklogService.save(tasklogEntity);
                
                //查询流程配置的回调函数
                ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(task.getTaskDefinitionKey());
                //如果该节点配置有回调函数，则执行回调
                if(nodesetEntity != null){
                	CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.START.getType());
                }
            }
            //如果第一个节点是结束节点 也就是空流程
        }else if(Constant.NodeType.END.getValue().equals(processTaskDto.getNodeType())){
            tasklog.setAppOpinion("空流程结束");
            //流程完成后，更改当前业务表的流程信息
            //更新流程业务关系表
            ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
            flowbusEntity.setBusId(processTaskDto.getBusId());
            flowbusEntity.setStatus(Constant.ActStauts.END.getValue());
            flowbusService.updateByBusId(flowbusEntity);
            //获取下一个人工任务节点，进行回调执行
            ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processTaskDto.getDefId());
            //获取流程定义的全部节点
            List<ActivityImpl> activities = processDefinitionEntity.getActivities();
            for(ActivityImpl node:activities){
                //节点类型为结束节点
                String type = (String)node.getProperty("type");
                if("endEvent".equals(type)){
                    //查询流程配置的回调函数
                    ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(node.getId());
                    //如果该节点配置有回调函数，则执行回调
                    if(nodesetEntity != null){
                    	CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.END.getType());
                    }
                    //流程结束发送通知 待完善
                    // TODO: 2017/8/4 流程结束发送通知 待完善
                }
            }
        }else {
            throw new BussinessException(-1,"流程设计错误!");
        }
        //保存扩展任务日志
        tasklogService.save(tasklog);
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public InputStream getFlowImgByInstantId(String processInstanceId) {
        if(StringUtils.isEmpty(processInstanceId)){
            throw new BussinessException(-1,"获取流程图片失败，流程实例不能为空!");
        }
        return ActUtils.getFlowImgByInstantId(processInstanceId);
    }

    @SuppressWarnings("unchecked")
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
    public Page<ProcessTaskDto> findMyUpcomingPage(Map<String,Object> params,int pageNum,LoginUser user) {
        PageHelper.startPage(pageNum, Constant.pageSize);
        //超级管理员可查看所有待办
        if(!user.isSuperManager()){
            params.put("dealId",user.getUserId());
        }
        actExtendMapper.findMyUpcomingPage(params);
        return PageHelper.endPage();
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public int myUpcomingCount(LoginUser user) {
        Map<String,Object> params = new HashMap<String,Object>();
        //超级管理员可查看所有待办
        if(!user.isSuperManager()){
            params.put("dealId",user.getUserId());
        }
        int count = 0;
        List<ProcessTaskDto> myUpcomingPage = actExtendMapper.findMyUpcomingPage(params);
        if(myUpcomingPage != null){
            count=myUpcomingPage.size();
        }
        return count;
    }

    @SuppressWarnings("unchecked")
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
    public Page<ProcessTaskDto> myDonePage(Map<String, Object> params, int pageNum,LoginUser user) {
        PageHelper.startPage(pageNum, Constant.pageSize);
        //超级管理员可查看所有待办
        if(!user.isSuperManager()){
            params.put("dealId",user.getUserId());
        }
        actExtendMapper.findMyDoneList(params);
        return PageHelper.endPage();
    }

    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public List<ProcessNodeDto> getNextActNodes(ProcessTaskDto processTaskDto) {
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw  new BussinessException(-1,"流程定义id不能为空!");
        }
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw  new BussinessException(-1,"流程任务id不能为空!");
        }
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
       
        Map<String,Object> elMap = new HashMap<String,Object>();
        
        ExtendActNodeset thisNodeSet = nodesetService.queryByNodeId(task.getTaskDefinitionKey());
        try {
			CallBackUtil.setVariables(thisNodeSet, processTaskDto, elMap);
		} catch (Exception e) {
			throw new BussinessException(-1,"设置流程变量错误");
		}
        
        List<PvmActivity> pvmActivities = ActUtils.getNextActNodes(processTaskDto.getDefId(), task.getTaskDefinitionKey(), elMap);
        List<ProcessNodeDto> listNode = new ArrayList<ProcessNodeDto>();
        ProcessNodeDto processNodeDto= null;
        for (PvmActivity pvm:pvmActivities){
            processNodeDto = new ProcessNodeDto();
            processNodeDto.setNodeId(pvm.getId());
            processNodeDto.setNodeName((String) pvm.getProperty("name"));
            ExtendActNodeset nodeSet = nodesetService.queryByNodeId(pvm.getId());
            if(ObjectUtil.isNotNull(nodeSet)){
                  processNodeDto.setNodeAction(nodeSet.getNodeAction());
                  processNodeDto.setNodeType(nodeSet.getNodeType());
            }
            listNode.add(processNodeDto);
        }
        return listNode;
    }
    

 
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void doActTask(ProcessTaskDto processTaskDto,Map<String,Object> map,LoginUser user) throws Exception {
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"流程任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getBusId())){
            throw new BussinessException(-1,"业务id不能为空");
        }
        //根据流程定义id查询流程定义key
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processTaskDto.getDefId()).singleResult();
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        //保存审批信息
        String remark="";
        if(StringUtils.isNotEmpty(processTaskDto.getRemark())){
            remark=processTaskDto.getRemark();
            taskService.addComment(processTaskDto.getTaskId(),processTaskDto.getInstanceId(),remark);
        }
        //查询流程业务关联信息
        ExtendActBusiness businessEntity = businessService.queryByActKey(processDefinition.getKey());
        ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(task.getTaskDefinitionKey());

        //流程变量
        Map<String,Object> elMap = new HashMap<String,Object>();
        CallBackUtil.setVariables(nodesetEntity,processTaskDto,elMap);
        //获取下个节点信息
        List<PvmActivity> pvmActivities = ActUtils.getNextActNodes(processTaskDto.getDefId(), task.getTaskDefinitionKey(), elMap);
        for (PvmActivity pvmActivity:pvmActivities) {
            //下一节点为结束节点时，完成任务更新业务表
            if ("endEvent".equals(pvmActivity.getProperty("type"))) {
                //查询结束节点信息（主要查询回调）
                ExtendActNodeset endNodeSet = nodesetService.queryByNodeId(pvmActivity.getId());
                //提交任务设置流程变量
                taskService.complete(task.getId(), elMap);
                //当前节点为会签节点时
                if (Constant.ActAction.MULIT.getValue().equals(nodesetEntity.getNodeAction())) {
                    //检测任务是否全部提交完
                    //会签是否全部执行完
                    boolean isAllCompleted = true;
                    //查询实例中的任务是否全部提交完
                    List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(task.getProcessInstanceId()).list();
                    for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                        if (historicTaskInstance.getEndTime() == null) {
                            isAllCompleted = false;
                            break;
                        }
                    }
                    //全部执行完，修改业务表
                    if (isAllCompleted) {
                        ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
                        flowbusEntity.setStatus(Constant.ActStauts.END.getValue());
                        flowbusEntity.setBusId(processTaskDto.getBusId());
                        flowbusService.updateByBusId(flowbusEntity);
                        //会签节点结束后,执行当前节点上的回调
                        CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.APPLY.getType());
                        //执行结束节点回调
                        CallBackUtil.executeCallback(endNodeSet,processTaskDto,RunType.END.getType());
                        
                    }
                } else if (Constant.ActAction.APPROVE.getValue().equals(nodesetEntity.getNodeAction())) {
                    ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
                    flowbusEntity.setStatus(Constant.ActStauts.END.getValue());
                    flowbusEntity.setBusId(processTaskDto.getBusId());
                    flowbusService.updateByBusId(flowbusEntity);
                    //执行当前节点上的回调
                    CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.APPLY.getType());
                    
                    //执行结束节点回调
                    CallBackUtil.executeCallback(endNodeSet,processTaskDto,RunType.END.getType());
                    
                }
                //流程结束可以在这里写一些通知信息
                ExtendActFlowbus flowBus = flowbusService.queryByBusIdInsId(processTaskDto.getInstanceId(), processTaskDto.getBusId());
                sendNoticeMsg(flowBus.getStartUserId(),businessEntity);
            } else {
              //下一个节点不为结束节点
                //查询下个节点信息
                ExtendActNodeset nextNode = nodesetService.queryByNodeId((String) pvmActivity.getId());
                //执行结束节点回调
                CallBackUtil.executeCallback(nodesetEntity,processTaskDto,RunType.APPLY.getType());
                //下一级节点为会签节点
                if(Constant.ActAction.MULIT.getValue().equals(nextNode.getNodeAction())){
                    // TODO: 2017/8/10 暂不支持当前节点为会签，下一级节点也为会签
                    //设置会签人员集
                    String[] nextUsers = processTaskDto.getNextUserIds().split(",");
                    Map<String,Object> userMap = new HashMap<String,Object>();
                    userMap.put(Constant.ACT_MUIT_LIST_NAME,Arrays.asList(nextUsers));
                    userMap.putAll(elMap);
                    //完成任务并设置流程变量
                    taskService.complete(task.getId(),userMap);
                    //查询流程所有任务
                    List<Task> taskList = taskService.createTaskQuery().processInstanceId(processTaskDto.getInstanceId()).list();
                    for (Task t:taskList){
                        //记录任务日志
                        ExtendActTasklog tasklogEntity = new ExtendActTasklog();
                        tasklogEntity.setId(UUIDUtil.getUUID());
                        tasklogEntity.setBusId(processTaskDto.getBusId());
                        tasklogEntity.setDefId(processTaskDto.getDefId());
                        tasklogEntity.setInstanceId(processTaskDto.getInstanceId());
                        tasklogEntity.setTaskId(t.getId());
                        tasklogEntity.setTaskName(t.getName());
                        tasklogEntity.setAdvanceId(t.getAssignee());
                        tasklogEntity.setCreateTime(task.getCreateTime());
                        tasklogService.save(tasklogEntity);
                    }
                    //下级节点为普通审批节点
                }else if (Constant.ActAction.APPROVE.getValue().equals(nextNode.getNodeAction())){
                     //完成任务
                    taskService.complete(task.getId(),elMap);
                    //会签是否结束
                    boolean isOver = true;
                    //当前节点为会签节点
                    if(Constant.ActAction.MULIT.getValue().equals(nodesetEntity.getNodeAction())){
                        List<Task> nodeTasks = taskService.createTaskQuery().taskDefinitionKey(nodesetEntity.getNodeId()).processInstanceId(processTaskDto.getInstanceId()).list();
                        if(nodeTasks.size()>0){
                            isOver=false;
                        }
                    }
                    if(isOver){
                        //如果会签已经完成，则记录下一任务日志
                        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processTaskDto.getInstanceId()).list();
                        for (Task t:tasks){
                            //设置下一个任务的办理人
                            // TODO: 2017/8/10 如果是下个节点是并行结果，那么这里需要处理下 待开发
                            taskService.setAssignee(t.getId(), processTaskDto.getNextUserIds());
                            ExtendActTasklog tasklogEntity = new ExtendActTasklog();
                            tasklogEntity.setId(UUIDUtil.getUUID());
                            tasklogEntity.setBusId(processTaskDto.getBusId());
                            tasklogEntity.setDefId(processTaskDto.getDefId());
                            tasklogEntity.setInstanceId(processTaskDto.getInstanceId());
                            tasklogEntity.setTaskId(t.getId());
                            tasklogEntity.setTaskName(t.getName());
                            tasklogEntity.setAdvanceId(processTaskDto.getNextUserIds());
                            tasklogEntity.setCreateTime(task.getCreateTime());
                            tasklogService.save(tasklogEntity);
                        }
                    }
                }
            }
        }
        //处理任务后，更新任务日志
        ExtendActTasklog tasklogEntity = new ExtendActTasklog();
        tasklogEntity.setTaskId(task.getId());
        tasklogEntity.setDealTime(new Date());
        tasklogEntity.setAppOpinion(remark);
        tasklogEntity.setDealId(user.getUserId());
        tasklogEntity.setColumns("");
        tasklogEntity.setAppAction(Constant.ActTaskResult.AGREE.getValue());
        int i = tasklogService.updateByTaskId(tasklogEntity);
        if(i<1){
            throw new BussinessException(-1,"更新任务日志失败");
        }
    }

    /**
     * 发送待办消息
     */
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void sendNoticeMsg(String userId,ExtendActBusiness businessEntity){
       /* NoticeEntity noticeEntity = new NoticeEntity();
        noticeEntity.setTitle("流程通知【"+businessEntity.getName()+"】");
        noticeEntity.setContext("亲，你提交的流程【"+businessEntity.getName()+"】已经审批结束了,请查阅对应模块！");
        noticeEntity.setCreateTime(new Date());
        noticeEntity.setIsUrgent(Constant.YESNO.YES.getValue());
        noticeEntity.setReleaseTimee(new Date());
        noticeEntity.setSoucre(Constant.noticeType.ACT_NOTICE.getValue());
        noticeEntity.setId(Utils.uuid());
        noticeEntity.setStatus(Constant.YESNO.YES.getValue());
        noticeUserEntity noticeUserEntity = new NoticeUser();
        noticeUserEntity.setId(Utils.uuid());
        noticeUserEntity.setNoticeId(noticeEntity.getId());
        noticeUserEntity.setStatus(Constant.YESNO.NO.getValue());
        noticeUserEntity.setUserId(userId);
        noticeService.save(noticeEntity);
        noticeUserDao.save(noticeUserEntity);*/
    }
    
    @Transactional(propagation=Propagation.NOT_SUPPORTED)
    public boolean hasPreNode(ProcessTaskDto processTaskDto,LoginUser user) throws Exception{
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getActKey())){
            throw new BussinessException(-1,"流程定义KEY");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例不能为空");
        }
       
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        //获取上一节点ID
        String preNodeId = ActUtils.getProActivityId(processTaskDto.getActKey(),task.getTaskDefinitionKey(),task.getProcessDefinitionId(),processTaskDto.getInstanceId(),null);
        if(ObjectUtil.isNull(preNodeId)){
        	return false;
        }
        return true;
    }
    
    
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void backPreviousNode(ProcessTaskDto processTaskDto,LoginUser user) throws Exception{
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getBusId())){
            throw new BussinessException(-1,"业务id不能为空");
        }
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        //获取上节点信息
        //获取上一节点ID
        String preNodeId = ActUtils.getProActivityId(processTaskDto.getActKey(),task.getTaskDefinitionKey(),task.getProcessDefinitionId(),processTaskDto.getInstanceId(),null);
        if(StringUtils.isEmpty(preNodeId)){
            throw new BussinessException(-1,"无法找到上一节点");
        }
        Map<String, Object> variables = new HashMap<>();
        ExtendActNodeset nodeSet = nodesetService.queryByNodeId(preNodeId);
        
        CallBackUtil.setVariables(nodeSet, processTaskDto, variables);
        
        List<NewTaskInfo> newTasks =  ActUtils.backProcess(processTaskDto.getTaskId(), preNodeId, variables, processTaskDto.getRemark());
        //新增驳回的任务日志 
        for(NewTaskInfo newTaskInfo:newTasks){
        	 //更新流程扩展日志表
             ExtendActTasklog taskLog = new ExtendActTasklog();
             Date date = new Date();
             taskLog.setId(UUIDUtil.getUUID());
             taskLog.setTaskId(newTaskInfo.getTaskId());
             taskLog.setAppOpinion(processTaskDto.getRemark());
             taskLog.setDealId(newTaskInfo.getUserId());
             taskLog.setDealTime(date);
             tasklogService.save(taskLog);
         }
      
        //执行结束节点回调
        CallBackUtil.cancelExecuteCallback(nodeSet,processTaskDto,RunType.BACK.getType());
        //更新流程为驳回
        //更新流程扩展日志表
        ExtendActTasklog taskLog = new ExtendActTasklog();
        Date date = new Date();
        taskLog.setTaskId(processTaskDto.getTaskId());
        taskLog.setAppOpinion(processTaskDto.getRemark());
        taskLog.setDealId(user.getUserId());
        taskLog.setDealTime(date);
        taskLog.setAppAction(Constant.ActTaskResult.TURN_DOWN.getValue());
        tasklogService.updateByTaskId(taskLog);
    }

 
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void backStartUser(ProcessTaskDto processTaskDto,Map<String,Object> map,LoginUser user) throws Exception {
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例不能为空");
        }
        //查询流程业务基本信息
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(task.getTaskDefinitionKey());
        //ExtendActBusiness actBus = businessService.queryByActKey(ActUtils.findProcessDefinitionEntityByTaskId(task.getId()).getKey());

        ActivityImpl endNode = ActUtils.findActivitiImpl(processTaskDto.getTaskId(), "end");
        ActUtils.turnTransition(processTaskDto.getTaskId(),endNode.getId(),null,processTaskDto.getRemark());
        //更新流程扩展日志表
        ExtendActTasklog taskLog = new ExtendActTasklog();
        Date date = new Date();
        taskLog.setTaskId(processTaskDto.getTaskId());
        taskLog.setAppOpinion(processTaskDto.getRemark());
        taskLog.setDealId(user.getUserId());
        taskLog.setDealTime(date);
        taskLog.setAppAction(Constant.ActTaskResult.TURN_DOWN.getValue());
        tasklogService.updateByTaskId(taskLog);
        //更新业务状态信息 
        ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
        flowbusEntity.setStatus(Constant.ActStauts.APPROVAL.getValue());
        flowbusEntity.setBusId(processTaskDto.getBusId());
        flowbusService.updateByBusId(flowbusEntity);
        //执行回调方法
        //执行结束节点回调
        CallBackUtil.cancelExecuteCallback(nodesetEntity,processTaskDto,RunType.BACK_START_USER.getType());
        ExtendActModel actModel = extendActModelService.queryByModelId(nodesetEntity.getModelId());
        ActNode actNode = this.getStartFlowInfo(actModel.getDeploymentId());
        if(actNode == null){
        	throw new BussinessException(-1, "无法找到开始节点");
        }
        //从新开始流程
        //设置用户为流程启动用户
        processTaskDto.setNextUserIds(processTaskDto.getStartUserId());
        startFlow(processTaskDto, actNode, user);
    }

    
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void stopFlow(ProcessTaskDto processTaskDto,Map<String,Object> map,LoginUser user) throws Exception {
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例不能为空");
        }
        //查询流程业务基本信息
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        ExtendActNodeset nodesetEntity = nodesetService.queryByNodeId(task.getTaskDefinitionKey());
       // ExtendActBusiness actBus = businessService.queryByActKey(ActUtils.findProcessDefinitionEntityByTaskId(task.getId()).getKey());

        ActivityImpl endNode = ActUtils.findActivitiImpl(processTaskDto.getTaskId(), "end");
        ActUtils.turnTransition(processTaskDto.getTaskId(),endNode.getId(),null,processTaskDto.getRemark());
        //更新流程扩展日志表
        ExtendActTasklog taskLog = new ExtendActTasklog();
        Date date = new Date();
        taskLog.setTaskId(processTaskDto.getTaskId());
        taskLog.setAppOpinion(processTaskDto.getRemark());
        taskLog.setDealId(user.getUserId());
        taskLog.setDealTime(date);
        taskLog.setAppAction(Constant.ActTaskResult.TURN_DOWN.getValue());
        tasklogService.updateByTaskId(taskLog);
        //更新业务状态信息 
        ExtendActFlowbus flowbusEntity = new ExtendActFlowbus();
        flowbusEntity.setStatus(Constant.ActStauts.APPROVAL.getValue());
        flowbusEntity.setBusId(processTaskDto.getBusId());
        flowbusService.updateByBusId(flowbusEntity);
        //执行回调方法
        //执行结束节点回调
        CallBackUtil.cancelExecuteCallback(nodesetEntity,processTaskDto,RunType.CANCAL.getType());
        //从新开始流程
    }
 
    @Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class) 
    public void turnToDo(ProcessTaskDto processTaskDto,String toUserId,LoginUser user) {
        if(StringUtils.isEmpty(processTaskDto.getTaskId())){
            throw new BussinessException(-1,"任务id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getDefId())){
            throw new BussinessException(-1,"流程定义id不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getInstanceId())){
            throw new BussinessException(-1,"流程实例不能为空");
        }
        if(StringUtils.isEmpty(processTaskDto.getBusId())){
            throw new BussinessException(-1,"业务id不能为空");
        }
        //转办任务
        Task task = taskService.createTaskQuery().taskId(processTaskDto.getTaskId()).singleResult();
        //转办
        ActUtils.transferAssignee(processTaskDto.getTaskId(),toUserId);
        //记录任务日志 先更新当前任务的日志，再为转办后任务新增一条任务日志
        ExtendActTasklog updateLog = new ExtendActTasklog();
        updateLog.setAppAction(Constant.ActTaskResult.TURN_DO.getValue());
        updateLog.setTaskId(task.getId());
        updateLog.setAppOpinion(processTaskDto.getRemark());
        updateLog.setDealId(user.getUserId());
        updateLog.setDealTime(new Date());
        tasklogService.updateByTaskIdOpinion(updateLog);
        //为置办任务新增一条任务日志
        ExtendActTasklog tasklogEntity = new ExtendActTasklog();
        tasklogEntity.setId(UUIDUtil.getUUID());
        tasklogEntity.setBusId(processTaskDto.getBusId());
        tasklogEntity.setDefId(processTaskDto.getDefId());
        tasklogEntity.setInstanceId(processTaskDto.getInstanceId());
        tasklogEntity.setTaskId(task.getId());
        tasklogEntity.setTaskName(task.getName());
        tasklogEntity.setAdvanceId(toUserId);
        tasklogEntity.setCreateTime(task.getCreateTime());
        tasklogService.save(tasklogEntity);
    }


	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public ExtendActNodeset getNodeSetByTaskId(String taskId) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
	      return  nodesetService.queryByNodeId(task.getTaskDefinitionKey());
	}

	
}
